package com.qinsheng.infrastructure.persistent.repository;

import cn.bugstack.middleware.db.router.strategy.IDBRouterStrategy;
import com.alibaba.fastjson.JSON;
import com.qinsheng.domain.award.model.aggregate.UserAwardRecordAggregate;
import com.qinsheng.domain.award.model.entity.TaskEntity;
import com.qinsheng.domain.award.model.entity.UserAwardRecordEntity;
import com.qinsheng.domain.award.repository.IAwardRepository;
import com.qinsheng.infrastructure.event.EventPublisher;
import com.qinsheng.infrastructure.persistent.dao.ITaskDao;
import com.qinsheng.infrastructure.persistent.dao.IUserAwardRecordDao;
import com.qinsheng.infrastructure.persistent.dao.IUserRaffleOrderDao;
import com.qinsheng.infrastructure.persistent.po.Task;
import com.qinsheng.infrastructure.persistent.po.UserAwardRecord;
import com.qinsheng.infrastructure.persistent.po.UserRaffleOrder;
import com.qinsheng.types.enums.ResponseCode;
import com.qinsheng.types.exception.AppException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;

/**
 * ClassName: AwardRepository
 * Description:
 *
 * @Author: qinsheng1900
 * @Create 2025/3/14 21:01
 * @Version 1.0
 */
@Slf4j
@Repository
public class AwardRepository implements IAwardRepository {
    @Resource
    private ITaskDao taskDao;
    @Resource
    private IUserAwardRecordDao userAwardRecordDao;
    @Resource
    private IDBRouterStrategy dbRouter;
    @Resource
    private TransactionTemplate transactionTemplate;
    @Resource
    private EventPublisher eventPublisher;
    @Resource
    private IUserRaffleOrderDao userRaffleOrderDao;


    @Override
    public void saveUserAwardRecord(UserAwardRecordAggregate userAwardRecordAggregate) {
        // 1.拿到实体
        UserAwardRecordEntity userAwardRecordEntity = userAwardRecordAggregate.getUserAwardRecordEntity();
        TaskEntity taskEntity = userAwardRecordAggregate.getTaskEntity();
        String userId = userAwardRecordEntity.getUserId();
        Long activityId = userAwardRecordEntity.getActivityId();
        Integer awardId = userAwardRecordEntity.getAwardId();

        // 2. entitiy格式转化
        UserAwardRecord userAwardRecord = new UserAwardRecord();
        userAwardRecord.setUserId(userAwardRecordEntity.getUserId());
        userAwardRecord.setActivityId(userAwardRecordEntity.getActivityId());
        userAwardRecord.setStrategyId(userAwardRecordEntity.getStrategyId());
        userAwardRecord.setOrderId(userAwardRecordEntity.getOrderId());
        userAwardRecord.setAwardId(userAwardRecordEntity.getAwardId());
        userAwardRecord.setAwardTitle(userAwardRecordEntity.getAwardTitle());
        userAwardRecord.setAwardTime(userAwardRecordEntity.getAwardTime());
        userAwardRecord.setAwardState(userAwardRecordEntity.getAwardState().getCode());

        Task task = new Task();
        task.setUserId(taskEntity.getUserId());
        task.setTopic(taskEntity.getTopic());
        task.setMessage(JSON.toJSONString(taskEntity.getMessage()));
        task.setMessageId(taskEntity.getMessageId());
        task.setState(taskEntity.getState().getCode());

        UserRaffleOrder userRaffleOrderReq = new UserRaffleOrder();
        userRaffleOrderReq.setUserId(userAwardRecordEntity.getUserId());
        userRaffleOrderReq.setOrderId(userAwardRecordEntity.getOrderId());


        //事务存储
        try{
           dbRouter.doRouter(userId);
           transactionTemplate.execute(status -> {
               try{
                   //写入用户抽奖记录
                   userAwardRecordDao.insert(userAwardRecord);
                   //写入任务记录
                   taskDao.insert(task);
                   //更新抽奖单
                   int count = userRaffleOrderDao.updateUserRaffleOrderStateUsed(userRaffleOrderReq);

                   if(1 != count){
                       status.setRollbackOnly();
                       log.error("写入中奖记录，用户抽奖单已使用过，不可重复抽奖 userId: {} activityId: {} awardId: {}", userId, activityId, awardId);
                       throw new AppException(ResponseCode.ACTIVITY_ORDER_ERROR.getCode(), ResponseCode.ACTIVITY_ORDER_ERROR.getInfo());
                   }

                   return 1;
               }catch(DuplicateKeyException e){
                   //事务失败，回滚
                   status.setRollbackOnly();
                   log.error("写入中奖记录，唯一索引冲突 userId: {} activityId: {} awardId: {}", userId, activityId, awardId, e);
                   throw new AppException(ResponseCode.INDEX_DUP.getCode(), e);
               }
           });
        } finally {
            dbRouter.clear();
        }
        //Task-MQ发送
        try{
            //发送消息【在事务外执行，如果失败还有任务补偿】
            eventPublisher.publish(task.getTopic(), task.getMessage());
            //更新数据库记录，task任务表
            taskDao.updateTaskSendMessageCompleted(task);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
}
